package com.pl.code.desktop.core;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.pl.code.desktop.entity.po.datasource.PlDataSource;
import com.pl.core.utils.ApplicationContextUtils;
import com.pl.datasource.dynamic.constants.ConnectionTypeEnum;
import com.pl.datasource.dynamic.constants.DbTypeEnum;
import com.pl.datasource.dynamic.constants.UrlPatternEnum;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @ClasssName DataSourceHelper
 * @Description 数据源工具类
 * @Author Liuyh
 * @Date 2021/9/16
 * @Version V0.0.1
 */
@Slf4j
@UtilityClass
public class DataSourceHelper {

    /**
     * 验证数据源
     *
     * @param url
     * @param username
     * @param password
     * @return
     */
    public Boolean checkDataSource(String url, String username, String password) {
        /*String url = conf.getUrl();
        if (ConnectionTypeEnum.HOST.typeEquals(conf.getConnectionType())) {
            UrlPatternEnum urlPattern = UrlPatternEnum.get(conf.getDbType());
            url = urlPattern.of(conf.getHost(), conf.getPort(), conf.getDbName());
        }*/
        try (Connection connection = DriverManager.getConnection(url, username, password)) {
        } catch (SQLException e) {
            log.error("数据源配置 {} , 获取链接失败", username, e);
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
    /**
     * 新增数据源
     *
     * @param dbType
     * @param name
     * @param url
     * @param username
     * @param password
     * @return
     */
    public boolean add(DbTypeEnum dbType, String name, String url, String username, String password) {
        DataSourceCreator dataSourceCreator = ApplicationContextUtils.getBean(DataSourceCreator.class);
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        dataSourceProperty.setPoolName(name);
        dataSourceProperty.setUrl(url);
        dataSourceProperty.setUsername(username);
        dataSourceProperty.setPassword(password);
        DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);

        DynamicRoutingDataSource dynamicRoutingDataSource = ApplicationContextUtils.getBean(DynamicRoutingDataSource.class);
        dynamicRoutingDataSource.addDataSource(dataSourceProperty.getPoolName(), dataSource);
        return Boolean.TRUE;
    }

    /**
     * 新增数据源
     *
     * @param dbType
     * @param name
     * @param host
     * @param port
     * @param database
     * @param username
     * @param password
     * @return
     */
    public boolean add(DbTypeEnum dbType, String name, String host, String port, String database, String username, String password) {
        UrlPatternEnum urlPattern = UrlPatternEnum.get(dbType.name());
        String url = urlPattern.of(host, port, database);
        return add(dbType, name, url, username, password);
    }

    /**
     * 关闭数据源
     *
     * @param name
     * @return
     */
    public Boolean close(String name) {
        DynamicRoutingDataSource dynamicRoutingDataSource = ApplicationContextUtils.getBean(DynamicRoutingDataSource.class);
        dynamicRoutingDataSource.removeDataSource(name);
        return Boolean.TRUE;
    }

    /**
     * 关闭数据源
     *
     * @param names
     * @return
     */
    public Boolean close(String... names) {
        DynamicRoutingDataSource dynamicRoutingDataSource = ApplicationContextUtils.getBean(DynamicRoutingDataSource.class);
        for (String name : names) {
            dynamicRoutingDataSource.removeDataSource(name);
        }
        return Boolean.TRUE;
    }

    /**
     * 更新数据源
     *
     * @param dbType
     * @param name
     * @param url
     * @param username
     * @param password
     * @return
     */
    public Boolean update(DbTypeEnum dbType, String name, String url, String username, String password) {
        if (!checkDataSource(url, username, password)) {
            return Boolean.FALSE;
        }
        // 关闭旧的数据源
        close(name);
        return add(dbType, name, url, username, password);
    }

    /**
     * 更新数据源
     *
     * @param dbType
     * @param name
     * @param host
     * @param port
     * @param database
     * @param username
     * @param password
     * @return
     */
    public boolean update(DbTypeEnum dbType, String name, String host, String port, String database, String username, String password) {
        UrlPatternEnum urlPattern = UrlPatternEnum.get(dbType.name());
        String url = urlPattern.of(host, port, database);
        return update(dbType, name, url, username, password);
    }


    /**
     * 添加数据源
     * @param dataSource
     * @return
     */
    public boolean add(PlDataSource dataSource) {
        DbTypeEnum dbType = DbTypeEnum.valueOf(dataSource.getDbType().toLowerCase());
        if (ConnectionTypeEnum.HOST.typeEquals(dataSource.getConnectionType())) {
            return add(dbType, dataSource.getName(), dataSource.getHost(), dataSource.getPort(), dataSource.getDbName(), dataSource.getUsername(), dataSource.getPassword());
        } else {
            return add(dbType, dataSource.getName(), dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
        }
    }

    /**
     * 更新数据源
     * @param dataSource
     * @return
     */
    public boolean update(PlDataSource dataSource){
        DbTypeEnum dbType = DbTypeEnum.valueOf(dataSource.getDbType().toLowerCase());
        if (ConnectionTypeEnum.HOST.typeEquals(dataSource.getConnectionType())) {
            return update(dbType, dataSource.getName(), dataSource.getHost(), dataSource.getPort(), dataSource.getDbName(), dataSource.getUsername(), dataSource.getPassword());
        } else {
            return update(dbType, dataSource.getName(), dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
        }
    }

}
